﻿using NJabber.Stream.Elements;
using NUnit.Framework;

namespace NJabber.Client.StanzaFactories
{
    [TestFixture]
    public class StanzaFactoryTest
    {
        [Test]
        public void CreateStanza_GenerateIdIsTrue_GeneratesId()
        {
            StanzaFactoryImpl factory = new StanzaFactoryImpl();
            factory.GenerateId = true;

            Stanza stanza = factory.CreateStanza();

            Assert.That(stanza.Id, Is.Not.Null);
        }

        [Test]
        public void CreateStanza_GenerateIdFalse_DoesNotGenerateId()
        {
            StanzaFactoryImpl factory = new StanzaFactoryImpl();
            factory.GenerateId = false;

            Stanza stanza = factory.CreateStanza();

            Assert.That(stanza.Id, Is.Null);
        }

        [Test]
        public void CreateStanza_SomeParameters_CreatesCorrectStanza()
        {
            StanzaFactoryImpl factory = new StanzaFactoryImpl();
            StanzaParameters parameters = CreateParameters("some-type", "from@jid.com", "to@jid.com", "ku");

            Stanza stanza = factory.CreateStanza(parameters);

            ValidateCreatedStanza(stanza, parameters);
        }

        [Test]
        public void CreateStanza_DefaultParameters_CreatesCorrectStanza()
        {
            StanzaFactoryImpl factory = new StanzaFactoryImpl();
            factory.DefaultParameters.Type = "some-type";
            factory.DefaultParameters.From = "from@jid.com";
            factory.DefaultParameters.To = "to@jid.com";
            factory.DefaultParameters.XmlLang = "fr";

            Stanza stanza = factory.CreateStanza();

            ValidateCreatedStanza(stanza, factory.DefaultParameters);
        }

        private static void ValidateCreatedStanza(Stanza stanza, StanzaParameters parameters)
        {
            Assert.That(stanza.Type, Is.EqualTo(parameters.Type));
            Assert.That(stanza.To, Is.EqualTo(parameters.To));
            Assert.That(stanza.From, Is.EqualTo(parameters.From));
            Assert.That(stanza.XmlLang, Is.EqualTo(parameters.XmlLang));
        }

        private StanzaParameters CreateParameters(string type, JID from, JID to, string xmlLang)
        {
            StanzaParameters parameters = new StanzaParameters();
            parameters.Type = type;
            parameters.From = from;
            parameters.To = to;
            parameters.XmlLang = xmlLang;
            return parameters;
        }
    }

    internal class StanzaFactoryImpl : StanzaFactory<StanzaParameters>
    {
        public Stanza CreateStanza()
        {
            return CreateStanza<MessageStanza>();
        }

        public Stanza CreateStanza(StanzaParameters parameters)
        {
            return CreateStanza<PresenceStanza>(parameters);
        }
    }
}
